#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <list>
#include <mutex>
#include <memory>
#include <thread>
#include <condition_variable>
#include <atomic>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

#define         ADAPTER_TEST            1

/**
 *          目标抽象类， 提供外部接口使用
*/
class Target
{
public:
    Target()
    {
        std::cout << "Target()" << endl;
    }
    virtual ~Target()
    {
        std::cout << "~Target()" << endl;
    }

    virtual void filter(const string &str) = 0;
};


/**
 *          适配者类
*/
class Adaptee_A
{
public:
    Adaptee_A()
    {
        std::cout << "Adaptee_A()" << endl;
    }
    ~Adaptee_A()
    {
        std::cout << "~Adaptee_A()" << endl;
    }

    void filterAdaptee(const string &str)
    {
        std::cout << __FUNCTION__ << " |str: " << str << endl;
    }
};


class Adaptee_B
{
public:
    Adaptee_B()
    {
        std::cout << "Adaptee_B()" << endl;
    }
    ~Adaptee_B()
    {
        std::cout << "~Adaptee_B()" << endl;
    }
    void filterAdaptee(const string &str, const string &maskStr)
    {
        std::cout << __FUNCTION__ << " |str: " << str << " |maskStr: " << maskStr << endl;
    }
};


/**
 *          适配器类
*/
class Adapter_A : public Target, public Adaptee_A
{
public:
    Adapter_A()
    {
        std::cout << "Adapter_A()" << endl;
    }

    ~Adapter_A() override
    {
        std::cout << "~Adapter_A()" << endl;
    }

    void filter(const string &str) override
    {
        filterAdaptee(str);
    }
};


class Adapter_B : public Target, public Adaptee_B
{
public:
    Adapter_B()
    {
        std::cout << "Adapter_B()" << endl;
    }
    ~Adapter_B() override
    {
        std::cout << "~Adapter_B()" << endl;
    }

    void filter(const string &str) override
    {
        filterAdaptee(str, m_maskStr);
    }

private:
    string m_maskStr = "MASK_B";
};


class ClassA
{
public:
    ClassA()
    {
        std::cout << "ClassA()" << endl;
    }
    virtual ~ClassA()
    {
        std::cout << "~ClassA()" << endl;
    }
};


class ClassA_Son : public ClassA
{
public:
    ClassA_Son()
    {
        std::cout << "ClassA_Son()" << endl;
    }
    ~ClassA_Son() override
    {
        std::cout << "~ClassA_Son()" << endl;
    }
};


// 测试接口
void testAdapterMode()
{
    std::list<unique_ptr<Target>> ptrVec;
    ptrVec.push_back(unique_ptr<Target>(new Adapter_A));
    ptrVec.push_back(unique_ptr<Target>(new Adapter_B));

    auto iter = ptrVec.begin();
    while ( iter != ptrVec.end() )
    {
        (*iter++)->filter(string("this is a Adapter Design Pattern Demo"));
    }
}



